package com.quickstart.wx.config;

import com.alibaba.fastjson.JSON;
import com.quickstart.common.http.HttpClientUtil;
import com.quickstart.common.other.PropertyUtil;
import com.quickstart.common.redies.RedisClient;
import com.quickstart.common.string.MyStringUtils;
import com.quickstart.wx.config.mode.WxMenuModel;
import com.quickstart.wx.config.mode.WxResponseJsonModel;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author:wesley
 */
@Component
public class WxCommonUtils {

    //项目地址，带有域名的
    private final String PROJECTURL = "http://weixiaobao.free.ngrok.cc";

    private final char[] digit = {'0', '1', '2', '3', '4', '5', '6',
            '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    @Autowired
    private RedisClient jedisClient;

    //获取accessToken
    private String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";

    //创建菜单
    private String createMenuUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=";

    //微信js-sdk的ticket
    private String jsapiTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=";

    private final String appId = "wxfabadcbf460fdf00";

    private final String secret = "9c7fb232ba19e4c7de497108b960159e";

    private final String token = "weixiaobao1990";

    private final String encodingAESKey = "MJ1nXxgNoGQXukiAoiiiPDirH6WhtxyT6ce1opi3ORb";

    private String getWxConfig(String param) {
        Map<String, String> map = PropertyUtil.getMapByPropertyFile("wx.properties");
        return map.get(param);
    }

//    public String getAppId() {
//        return appId;
//    }
//
//    public String getSecret() {
//        return secret;
//    }
//
//    public String getToken() {
//        return token;
//    }
//
//    public String getEncodingAESKey() {
//        return encodingAESKey;
//    }


    /**
     * 获取access_token或者ticket
     *
     * @param type 1:accessToken ; 2:ticket
     * @return 返回token或者ticket
     */
    public String getJsTicketOrAccessToken(int type) {
        String accessToken = jedisClient.get("wx_access_token");
        if (StringUtils.isBlank(accessToken)) {
            accessToken = getAccessToken();
        }

        String ticket = getJsapiTicket(accessToken);

        if (type == 1) {
            return accessToken;
        } else if (type == 2) {
            return ticket;
        } else {
            return null;
        }
    }


    /**
     * 获取accessToken， 有效期是2小时
     *
     * @return
     */
    private String getAccessToken() {

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("appid", this.appId);
        paramMap.put("secret", this.secret);
        paramMap.put("grant_type", "client_credential");


        String responsMsg = HttpClientUtil.doGet(accessTokenUrl, paramMap);
        if (StringUtils.isNotBlank(responsMsg)) {
            WxResponseJsonModel jsonModel = JSON.parseObject(responsMsg, WxResponseJsonModel.class);
            if (StringUtils.isBlank(jsonModel.getErrcode())) {
                String accessToken = jsonModel.getAccess_token();
                jedisClient.set("wx_access_token", accessToken);
                jedisClient.expire("wx_access_token", 7200);
                return accessToken;
            } else {
                System.out.println("*********************************************");
                System.err.println("请求微信Token错误：" + jsonModel.getErrmsg());
                System.out.println("*********************************************");
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * 获取微信的js的ticket
     *
     * @param accessToken
     * @return
     */
    private String getJsapiTicket(String accessToken) {
        String responsMsg = HttpClientUtil.doGet(jsapiTicketUrl + accessToken, null);
        if (StringUtils.isNotBlank(responsMsg)) {
            WxResponseJsonModel jsonModel = JSON.parseObject(responsMsg, WxResponseJsonModel.class);
            if (jsonModel.getErrcode().equals("0")) {
                String ticket = jsonModel.getTicket();
                jedisClient.set("wx_ticket", ticket);
                jedisClient.expire("wx_ticket", 7200);
                return ticket;
            } else {
                System.out.println("*********************************************");
                System.err.println("请求微信ticket错误：" + jsonModel.getErrmsg());
                System.out.println("*********************************************");
                return null;
            }
        } else {
            return null;
        }
    }


    /**
     * 签名生成规则如下：
     * 参与签名的字段包括noncestr（随机字符串）,有效的jsapi_ticket, timestamp（时间戳）, url（当前网页的URL，不包含#及其后面部分） 。
     * 对所有待签名参数按照字段名的ASCII 码从小到大排序（字典序）后，使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串string1。
     * 这里需要注意的是所有参数名均为小写字符。对string1作sha1加密，字段名和字段值都采用原始值，不进行URL 转义。
     *
     * @param jsapi_ticket jsskd的accessToken
     * @param url          请求的url ，不能带有#
     * @return
     */
    public Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = MyStringUtils.getNonceStr();
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        String string1;
        String signature = "";
        // 注意这里参数名必须全部小写，且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url=" + url;
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = MyStringUtils.byteToHex(crypt.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        ret.put("url", url);
        ret.put("appId", this.appId);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        return ret;
    }

    /**
     * 创建菜单
     */
    public void createMenu(String accessToken) {

        List<WxMenuModel> allMenu = new ArrayList<>();

        WxMenuModel bt1 = new WxMenuModel();
        bt1.setName("菜单1");
        WxMenuModel bt1_sub1 = new WxMenuModel();
        bt1_sub1.setType("view");
        bt1_sub1.setName("搜搜");
        bt1_sub1.setUrl("http://www.soso.com");
        List<WxMenuModel> sub1 = new ArrayList<>();
        sub1.add(bt1_sub1);
        bt1.setSub_button(sub1);

        WxMenuModel bt2 = new WxMenuModel();
        bt2.setName("菜单2");
        WxMenuModel bt2_sub1 = new WxMenuModel();
        bt2_sub1.setType("view");
        bt2_sub1.setName("百度");
        bt2_sub1.setUrl(PROJECTURL + "/web/login");
        List<WxMenuModel> sub2 = new ArrayList<>();
        sub2.add(bt2_sub1);
        bt2.setSub_button(sub2);

        allMenu.add(bt1);
        allMenu.add(bt2);

        Map<String, List<WxMenuModel>> map = new HashMap<>();
        map.put("button", allMenu);

        String responJson = HttpClientUtil.doPostJson(createMenuUrl + accessToken,
                JSON.toJSONString(map));

        System.out.println(responJson);
    }


}
